Imports System.Collections.Generic
Imports System.Linq
Imports System.Text
Imports Microsoft.Xna.Framework
Imports Microsoft.Xna.Framework.Audio
Imports Microsoft.Xna.Framework.Content
Imports Microsoft.Xna.Framework.GamerServices
Imports Microsoft.Xna.Framework.Graphics
Imports Microsoft.Xna.Framework.Input
Imports Microsoft.Xna.Framework.Media
Imports Microsoft.Xna.Framework.Input.Touch



Public Class Sprite
	Private m_sword As Boolean = False

	Public Const SPRITE_SIZE_X As Integer = 114
	'to be var
	Public Const SPRITE_SIZE_Y As Integer = 114
	'to be var
	Public Const PLAYER_L_PENETRATION As Integer = 19
	Public Const PLAYER_R_PENETRATION As Integer = 30

	Public Const PLAYER_STAND_BORDER_FRAME As Integer = 47
	'47+20player+47=114
	Public Const PLAYER_STAND_FRAME As Integer = 20
	Public Const PLAYER_STAND_WALL_PEN As Integer = 30
	'wall penetration
	Public Const PLAYER_STAND_FLOOR_PEN As Integer = 26
	'floor border penetration
	Public Const PLAYER_STAND_HANG_PEN As Integer = 46
	'floor border penetration for hangup
	Public startPosition As Vector2 = Vector2.Zero
	'where the sprite begins
	Public startFlip As SpriteEffects = SpriteEffects.None


	Protected spriteSequence As List(Of Sequence) = Nothing
	Protected graphicsDevice As GraphicsDevice
	Public flip As SpriteEffects = SpriteEffects.None
	Protected _position As Position = Nothing
	'protected Maze _maze;
	Protected m_velocity As Vector2
	Protected m_isOnGround As Boolean
	Protected localBounds As Rectangle
	Protected m_spriteRoom As RoomNew = Nothing

	Private m_alert As Boolean = False
	'set true when there is a enemy in the room or near
	Public sprite As AnimationSequence
	Public spriteState As New PlayerState()

	Public Property Sword() As Boolean
		Get
			Return m_sword
		End Get
		Set
			m_sword = value
		End Set
	End Property

	Public ReadOnly Property Maze() As Maze
		Get
			Return m_spriteRoom.maze
		End Get
	End Property

	' Alert state
	Public Property Alert() As Boolean
		Get
			Return m_alert
		End Get
		Set
			m_alert = value
		End Set
	End Property

	' Physics state
	Public Property SpriteRoom() As RoomNew
		Get
			Return m_spriteRoom
		End Get
		Set
			m_spriteRoom = value
		End Set
	End Property

	' Physics state, used by calculate falldrop distance
	Public Property PositionFall() As Vector2
		Get
			Return m_positionFall
		End Get
		Set
			m_positionFall = value
		End Set
	End Property
	Protected m_positionFall As Vector2 = Vector2.Zero


	Public ReadOnly Property IsAlive() As Boolean
		Get
			If m_energy > 0 Then
				Return True
			Else
				Return False
			End If
		End Get
	End Property
	'set { isAlive = value; }


	'How many energy triangle sprite have
	Public Property LivePoints() As Integer
		Get
			Return m_livePoints
		End Get
		Set
			m_livePoints = value
		End Set
	End Property
	Private m_livePoints As Integer = 3

	'energy...
	Public Property Energy() As Integer
		Get
			Return m_energy
		End Get
		Set
			m_energy = value
			If m_energy > m_livePoints Then
				m_energy = m_livePoints
			End If
		End Set
	End Property
	Private m_energy As Integer = 3


	Public ReadOnly Property Position() As Position
		Get
			Return _position
		End Get
	End Property

	Public Property Velocity() As Vector2
		Get
			Return m_velocity
		End Get
		Set
			m_velocity = value
		End Set
	End Property


	Public ReadOnly Property IsOnGround() As Boolean
		Get
			Return m_isOnGround
		End Get
	End Property
	''' <summary>
	''' Gets a rectangle which bounds this player in world space.
	''' </summary>
	Public ReadOnly Property BoundingRectangle() As Rectangle
		Get
			Dim left As Integer = CInt(Math.Truncate(Math.Round(_position.X))) + localBounds.X
			Dim top As Integer = CInt(Math.Truncate(Math.Round(_position.Y - sprite.Origin.Y))) + localBounds.Y

			Return New Rectangle(left, top, localBounds.Width, localBounds.Height)
		End Get
	End Property

	Public ReadOnly Property BoundingRectangleReal() As Rectangle
		Get
			Dim left As Integer = CInt(Math.Truncate(Math.Round(_position.X))) - (localBounds.Width)
			'square 114x114
			Dim top As Integer = CInt(Math.Truncate(Math.Round(_position.Y))) + localBounds.Y

			Return New Rectangle(left, top, localBounds.Width * 2, localBounds.Height)
		End Get
	End Property


	Public Function CheckCollision(position__1 As Position) As Boolean
		If position__1 Is Position Then
			Return True
		End If
		Return False
	End Function

	Public Function CheckOnRow(position__1 As Position) As Boolean
		If position__1.Y = Position.Y Then
			Return True
		End If
		Return False
	End Function


	Public Sub isGround()
		If IsAlive = False Then
			Return
		End If

		m_isOnGround = False

		Dim room As RoomNew = Nothing
		Dim playerBounds As Rectangle = _position.Bounding
		Dim v2 As Vector2 = SpriteRoom.getCenterTile(playerBounds)
		Dim tileBounds As Rectangle = SpriteRoom.GetBounds(CInt(Math.Truncate(v2.X)), CInt(Math.Truncate(v2.Y)))

		'Check if kid outside Room 
		If v2.X < 0 Then
			room = Maze.LeftRoom(SpriteRoom)
		Else
			room = SpriteRoom
		End If

		If v2.Y > 2 Then
			m_isOnGround = False
		ElseIf v2.Y < 0 Then
			m_isOnGround = False
		Else
			If room.GetCollision(CInt(Math.Truncate(v2.X)), CInt(Math.Truncate(v2.Y))) <> Enumeration.TileCollision.Passable Then
				If playerBounds.Bottom >= tileBounds.Bottom Then
					m_isOnGround = True
				End If
			End If
		End If


		If m_isOnGround = False Then
			If sprite.sequence.raised = False Then
				If spriteState.Value().state = Enumeration.State.runjump Then
					spriteState.Add(Enumeration.State.rjumpfall, Enumeration.PriorityState.Force)
					sprite.PlayAnimation(spriteSequence, spriteState.Value())
				Else
					If spriteState.Previous().state = Enumeration.State.runjump Then
						spriteState.Add(Enumeration.State.stepfall, Enumeration.PriorityState.Force, New Vector2(20, 15))
					ElseIf spriteState.Value().state <> Enumeration.State.freefall Then
						spriteState.Add(Enumeration.State.stepfall, Enumeration.PriorityState.Force)
					End If
				End If
				'SpriteRoom.LooseShake();
				'and for upper room...
				SpriteRoom.maze.UpRoom(SpriteRoom).LooseShake()
			End If
			Return
		End If


		'IS ON GROUND!
		If spriteState.Value().state = Enumeration.State.freefall Then
			'Align to tile x
			_position.Y = tileBounds.Bottom - _position._spriteRealSize.Y
			'CHECK IF LOOSE ENERGY...
			Dim [Rem] As Integer = 0
			[Rem] = CInt(Math.Truncate(Math.Abs(Position.Y - PositionFall.Y))) \ Tile.REALHEIGHT

			If [Rem] = 0 Then
				DirectCast(Maze.dContentRes("Sounds/dos/falling echo".ToUpper()), SoundEffect).Play()
			ElseIf [Rem] >= 1 And [Rem] < 3 Then
				DirectCast(Maze.dContentRes("Sounds/dos/loosing a life falling".ToUpper()), SoundEffect).Play()
			Else
				DirectCast(Maze.dContentRes("Sounds/dos/falling".ToUpper()), SoundEffect).Play()
				'you should dead!!!
				DeadFall()
			End If
			Energy = Energy - [Rem]
			spriteState.Add(Enumeration.State.crouch, Enumeration.PriorityState.Force, False)
			SpriteRoom.LooseShake()
		End If

	End Sub

	Public Sub DeadFall()
		spriteState.Add(Enumeration.State.deadfall, Enumeration.PriorityState.Force)
		sprite.PlayAnimation(spriteSequence, spriteState.Value())
	End Sub

	Public Sub DropDead()
		If spriteState.Value().state <> Enumeration.State.dropdead Then
			spriteState.Add(Enumeration.State.dropdead, Enumeration.PriorityState.Force)
			sprite.PlayAnimation(spriteSequence, spriteState.Value())
		End If
	End Sub

	Public Sub Resheathe()
		spriteState.Add(Enumeration.State.resheathe, Enumeration.PriorityState.Normal)
		sprite.PlayAnimation(spriteSequence, spriteState.Value())
	End Sub


	Public Sub Fastheathe()
		spriteState.Add(Enumeration.State.fastsheathe, Enumeration.PriorityState.Normal)
		sprite.PlayAnimation(spriteSequence, spriteState.Value())
	End Sub

	Public Sub Strike()
		spriteState.Add(Enumeration.State.strike, Enumeration.PriorityState.Normal)
		sprite.PlayAnimation(spriteSequence, spriteState.Value())
	End Sub

	Public Sub Retreat()
		spriteState.Add(Enumeration.State.retreat, Enumeration.PriorityState.Normal)
		sprite.PlayAnimation(spriteSequence, spriteState.Value())
	End Sub

	Public Sub StrikeRetreat()
		spriteState.Add(Enumeration.State.strikeret, Enumeration.PriorityState.Force)
		sprite.PlayAnimation(spriteSequence, spriteState.Value())
	End Sub


	'show splash hit
	Public Sub Splash(player As Boolean, gametime As GameTime)

		Dim splash__1 As New Splash(Maze.player.SpriteRoom, Position.Value, graphicsDevice, SpriteEffects.None, player)
		Maze.sprites.Add(splash__1)

	End Sub



	Public Sub New()
	End Sub
End Class
